package com.youlu.campus.web.community.service.impl;

import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.base.ContentTypeEnum;
import com.youlu.campus.base.base.GeneraStatusEnum;
import com.youlu.campus.base.base.InteractiveActionEnum;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.service.base.BaseService;

import com.youlu.campus.web.community.dto.*;
import com.youlu.campus.web.community.entity.TopicCount;
import com.youlu.campus.web.community.entity.TopicInfo;
import com.youlu.campus.web.community.service.TopicCountService;
import com.youlu.campus.web.community.service.TopicService;
import com.youlu.campus.web.common.utils.CommonUtils;
import com.youlu.campus.web.common.utils.IdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 话题信息接口实现类
 *
 * @author: YangJ
 * @date: 2020/11/24 18:15
 */
@Slf4j
@Service("topicService")
public class TopicServiceImpl extends BaseService implements TopicService {

    @Autowired
    private TopicCountService topicCountService;

//    @Autowired
//    private MQService mqService;

    @Override
    public Page<TopicPageResponse> topicPage(TopicQueryRequest request) {

        Query query = new Query();
        query.addCriteria(Criteria.where("status").is(GeneraStatusEnum.ON.getCode()));
        query.addCriteria(Criteria.where("deleted").is(false));
        long count = mongoTemplate.count(query, TopicInfo.class);

        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
        if (StringUtils.isNotBlank(request.getSortVal())
                && "new".equals(request.getSortVal())) {
//            query.with(new Sort(Sort.Direction.DESC, "createdTime"));
            Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
            query.with(sort);
        } else {
//            query.with(new Sort(Sort.Direction.DESC, "weight"));
//            query.with(new Sort(Sort.Direction.DESC, "hotCount"));
//            query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        }

        List<TopicInfo> topicInfos = mongoTemplate.find(query.with(pageRequest), TopicInfo.class);
        List<TopicPageResponse> list = topicInfos.stream().map(topicInfo -> {
            TopicResponse topicResponse = handleResponse(topicInfo);
            TopicPageResponse response = mapperFacade.map(topicResponse, TopicPageResponse.class);
            if (StringUtils.isBlank(response.getDiscussValue())) {
                response.setDiscussValue("0讨论");
            }
            if (StringUtils.isBlank(response.getHotValue())) {
                response.setHotValue("0热度");
            }
            return response;
        }).collect(Collectors.toList());
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    /**
     * 处理话题统计数据
     *
     * @param topicInfo
     * @return
     */
    private TopicResponse handleResponse(TopicInfo topicInfo) {
        TopicResponse response = mapperFacade.map(topicInfo, TopicResponse.class);
        response.setHotValue(CommonUtils.intChange2Str(topicInfo.getHotCount(), "热度"));
        Integer dv = topicInfo.getCommentCount()+topicInfo.getContentCount();
        response.setDiscussValue(CommonUtils.intChange2Str(dv, "讨论"));
        if (StringUtils.isNotBlank(topicInfo.getPkA())) {
            handleTopicPk(response);
        }
        if (StringUtils.isBlank(response.getDiscussValue())) {
            response.setDiscussValue("0讨论");
        }
        if (StringUtils.isBlank(response.getHotValue())) {
            response.setHotValue("0热度");
        }
        return response;
    }

    private void handleTopicPk(TopicResponse response) {
        TopicCountResponse percent = topicCountService.queryTopicCountPercent(response.getId());
        response.setPkAPercent(percent.getPkAPercent());
        response.setPkBPercent(percent.getPkBPercent());
        TopicCount topicCount = topicCountService.queryUserVoted(response.getId());
        if (topicCount != null) {
            response.setVoted(true);
            response.setVoteValue(topicCount.getSelectValue());
        }
    }

    @Override
    public TopicResponse queryTopicPk(String id) {

        TopicResponse response = new TopicResponse();
        response.setId(id);
        handleTopicPk(response);

        return response;
    }

    @Override
    public void handleStatus() {
        log.info("处理话题状态变更开始");

        Query query = new Query();
        query.addCriteria(Criteria.where("deleted").is(false));
        query.addCriteria(Criteria.where("status").is(GeneraStatusEnum.PENDING.getCode()));
        query.addCriteria(Criteria.where("startTime").lte(new Date()));
        Update update = new Update();
        update.set("status", GeneraStatusEnum.ON.getCode());
        update.set("updatedTime", new Date());
        UpdateResult result = mongoTemplate.updateMulti(query, update, TopicInfo.class);
        if (result.getModifiedCount() > 0) {
            log.info("话题变更为上架状态完毕,总条数:{}", result.getModifiedCount());
        }

        query = new Query();
        query.addCriteria(Criteria.where("deleted").is(false));
        query.addCriteria(Criteria.where("status").is(GeneraStatusEnum.ON.getCode()));
        query.addCriteria(Criteria.where("endTime").lte(new Date()));
        update = new Update();
        update.set("status", GeneraStatusEnum.OFF.getCode());
        update.set("updatedTime", new Date());
        UpdateResult result1 = mongoTemplate.updateMulti(query, update, TopicInfo.class);
        if (result1.getModifiedCount() > 0) {
            log.info("话题变更为下架状态完毕,总条数:{}", result1.getModifiedCount());
        }

        log.info("处理话题状态变更结束");
    }

    @Override
    public TopicResponse query(String id) {
        log.info("查询话题信息开始，id:{}", id);
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("话题ID不能为空!");
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        TopicInfo topicInfo = mongoTemplate.findOne(query, TopicInfo.class);
        if (topicInfo == null) {
            throw new BusinessException("话题信息查询失败!");
        }
        TopicResponse response = handleResponse(topicInfo);

        //维护话题统计信息-热度数(+1)
        InteractiveMqRequest req = new InteractiveMqRequest();
        req.setType(ContentTypeEnum.HT.getCode());
        req.setAction(InteractiveActionEnum.HOT.getCode());
        req.setBid(id);
        req.setValue(1);
//        mqService.sendNormal(req, CampusMQDefinition.ROUTING_KEY_INTERACTIVE);

        log.info("查询话题信息结束");
        return response;
    }


    @Override
    public List<TopicMenuResponse> hotList(String name) {

        Query query = new Query();
        query.addCriteria(Criteria.where("deleted").is(false));
        query.addCriteria(Criteria.where("type").is("general"));
        query.addCriteria(Criteria.where("status").is(GeneraStatusEnum.ON.getCode()));
        if (StringUtils.isNotBlank(name)) {
            Pattern pattern = Pattern.compile("^.*" + name + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("title").regex(pattern));
        }
        long count = mongoTemplate.count(query, TopicInfo.class);
        if (count <= 0){
            return new ArrayList<>();
        }
        long page = count / 4;
        if (count % 4 != 0){
            page ++;
        }
        log.info("总页数:{}",page);
        int num = IdGenerator.getRandNum(1, (int) page);
        PageRequest pageRequest = PageRequest.of(num, 4);
//        query.with(new Sort(Sort.Direction.DESC, "hotCount"));
        Sort sort=Sort.by(Sort.Direction.DESC, "hotCount");
        query.with(sort);
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        List<TopicInfo> topicInfoList = mongoTemplate.find(query.with(pageRequest), TopicInfo.class);

        List<TopicMenuResponse> list = topicInfoList.stream().map(topicInfo -> {
            TopicMenuResponse response = mapperFacade.map(topicInfo, TopicMenuResponse.class);
            return response;
        }).collect(Collectors.toList());

        log.info("查询最热门常规话题结束，总条数：{}", list.size());

        return list;
    }


}
